
from django import forms
from django.core.exceptions import ValidationError
from django.shortcuts import render,HttpResponse,redirect
from django.http import JsonResponse

from django01.models import Book
from django01.models import Admin

from django02.util.Pagination import Pagination
from django02.util.BootStrapModelForm import BootStrapModelForm

from django01.utils.encypt import md5
from io import BytesIO
from django01.utils.code import check_code

from django.views.decorators.csrf import csrf_exempt

# Create your views here.


def test(request):
    books = Book.objects.all()
    return render(request, 'test1.html', {'books':books})

def admin_list(request):
    data_dict = {}
    value = request.GET.get('query', '')  # 条件检索
    if value:
        data_dict["name__contains"] = value
    queryset = Admin.objects.filter(**data_dict)
    page_obj = Pagination(request, queryset)
    context = {
        'queryset': page_obj.page_queryset,
        'page_str': page_obj.html(),
        'value': value,
    }
    return render(request, 'admin_list.html',context)

class AdminModelForm(BootStrapModelForm):
    confirm_password = forms.CharField(
        label='确认密码',
        widget=forms.PasswordInput(render_value=True), # render_value=True 表示输入框不被清空
    )
    class Meta:
        model = Admin
        fields = ['name','password','confirm_password']
        widgets ={
            'password': forms.PasswordInput(render_value=True) # render_value=True 表示输入框不被清空
        }
    # 加密
    def clean_password(self):
        pwd = self.cleaned_data.get('password')
        md5_pwd = md5(pwd)

        # 修改时判断密码是否一致，获取数据中的密码，用存在 。 self.instance.pk 当前传过来的id
        exists = Admin.objects.filter(id=self.instance.pk,password=md5_pwd).exists()
        if exists:
            raise ValidationError('密码和原密码相同')

        return md5_pwd

    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm_password = md5(self.cleaned_data.get('confirm_password'))
        if password != confirm_password:
            raise ValidationError('密码不一致')
        return confirm_password  # 返回 输入的确认密码，如果要保存到数据库，存储的是用户输入的值

def admin_add(request):

    if request.method == 'GET':
        form = AdminModelForm()
        return render(request, 'admin_add.html', {'form':form})
    form = AdminModelForm(request.POST)
    if form.is_valid():
        form.save()
        return redirect('/d1/admin/')
    return render(request, 'admin_add.html', {'form':form})


def admin_edit(request,nid):
    row_object = Admin.objects.filter(id=nid).first()
    if request.method == 'GET':
        form = AdminModelForm(instance=row_object)
        return render(request, 'admin_edit.html', {'form':form})

    form = AdminModelForm(request.POST, instance=row_object)
    if form.is_valid():
        form.save()
        return redirect('/d1/admin/')
    return render(request, 'admin_edit.html', {'form':form})

def admin_delete(request,nid):
    Admin.objects.filter(id=nid).delete()
    return redirect('/d1/admin/')

def admin_reset(request,nid):
    Admin.objects.filter(id=nid).update(password=md5('123'))
    return redirect('/d1/admin/')


class LoginForm(forms.Form):
    name = forms.CharField(
        label='用户名',
        widget=forms.TextInput,
    )
    password = forms.CharField(
        label='密码',
        widget=forms.PasswordInput(render_value=True),
    )
    code = forms.CharField(
        label='图片验证码',
        widget=forms.TextInput,
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            # 如上需要保留原来的属性
            if field.widget.attrs:
                field.widget.attrs['class'] = 'form-control'
                field.widget.attrs['placeholder'] = field.label
            else:
                field.widget.attrs = {'class': 'form-control', 'placeholder': field.label}

    def clean_password(self):
        password = self.cleaned_data.get('password')
        md5_pwd = md5(password)
        return md5_pwd

def login(request):
    if request.method == 'GET':
        form = LoginForm()
        return render(request, 'login.html', {'form':form})

    form = LoginForm(request.POST)
    if form.is_valid():
        # form.cleaned_data: {'name': '001', 'password': 'd8f72151f191bc271623a9b38074680b', 'code': '信息'}
        input_code = form.cleaned_data.pop('code')  # 输入的验证码
        code = request.session.get('image_code','')  # 生成的验证码
        if input_code.upper() != code.upper():
            form.add_error('code', '验证码错误')
            return render(request, 'login.html', {'form':form})
        # print(form.cleaned_data)
        admin_obj = Admin.objects.filter(**form.cleaned_data).first()

        if not admin_obj:
            form.add_error('password','用户或密码错误')
            return render(request, 'login.html', {'form':form})

        request.session["info"] = {'id': admin_obj.id, 'name': admin_obj.name}
        # 这里需要重新设置session的有效时间，前面验证码设置了60秒，这里会默认60秒
        request.session.set_expiry(60 * 60 * 24 * 7)  # 7天内
        return redirect('/d1/admin/')
    return render(request, 'login.html', {'form':form})

def image_code(request):
    # 生成图片
    img, code_string = check_code()
    # 写入到自己的session中（以便于后续获取验证码再进行校验）
    request.session['image_code'] = code_string
    # 给Session设置60s超时
    request.session.set_expiry(60)  # 60秒
    stream = BytesIO()
    img.save(stream, 'png')
    return HttpResponse(stream.getvalue())

def logout(request):
    request.session.clear()
    return redirect('/d1/admin/')


def task_list(request):
    '''任务'''
    form=AdminModelForm()
    return render(request, 'task_list.html', {'form':form})

@csrf_exempt  #发送post时免除crsf_token 验证
def task_ajax(request):
    """ajax"""
    print(request.POST)
    # print(request.POST.get("n1"))
    # print(request.POST.get("n2"))
    data_dict = {'status':100,'data':request.POST}
    return JsonResponse(data_dict)

@csrf_exempt
def task_add(request):

    form = AdminModelForm(data=request.POST)
    if form.is_valid():
        form.save()
        data_dict = {'status':100,'data':form.cleaned_data}
        return JsonResponse(data_dict)

